#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
配置管理器
负责加载和管理配置文件
"""

import os
import yaml
from typing import Dict, Any, Optional
from dataclasses import dataclass
from pathlib import Path


@dataclass
class APIConfig:
    """API配置"""
    account: str
    password: str
    url: str
    debug: bool
    web_gui: bool


@dataclass
class StrategyConfig:
    """策略配置"""
    name: str
    symbol: str
    volume: int
    short_period: int
    long_period: int


@dataclass
class RiskConfig:
    """风险管理配置"""
    max_daily_loss: float
    max_single_loss: float
    max_position_size: int
    stop_loss_points: float
    take_profit_points: float
    enable_trailing_stop: bool
    trailing_stop_points: float


@dataclass
class DataConfig:
    """数据配置"""
    kline_period: int
    data_length: int
    cache_enabled: bool
    cache_ttl: int


@dataclass
class LoggingConfig:
    """日志配置"""
    level: str
    file_path: str
    max_file_size: int
    backup_count: int
    console_output: bool


@dataclass
class TradingConfig:
    """交易配置"""
    max_orders_per_minute: int
    order_timeout: int
    retry_attempts: int
    retry_delay: float
    enable_simulation: bool


@dataclass
class MonitoringConfig:
    """监控配置"""
    health_check_interval: int
    performance_report_interval: int
    enable_metrics: bool
    metrics_port: int


class ConfigManager:
    """配置管理器"""

    def __init__(self, config_file: str = None):
        """
        初始化配置管理器

        Args:
            config_file: 配置文件路径
        """
        if config_file is None:
            # 默认配置文件路径
            current_dir = Path(__file__).parent
            config_file = current_dir / "settings.yaml"

        self.config_file = Path(config_file)
        self._config = {}
        self._load_config()

        # 解析配置到数据类
        self.api = self._parse_api_config()
        self.strategy = self._parse_strategy_config()
        self.risk = self._parse_risk_config()
        self.data = self._parse_data_config()
        self.logging = self._parse_logging_config()
        self.trading = self._parse_trading_config()
        self.monitoring = self._parse_monitoring_config()

    def _load_config(self):
        """加载配置文件"""
        try:
            if not self.config_file.exists():
                raise FileNotFoundError(f"配置文件不存在: {self.config_file}")

            with open(self.config_file, 'r', encoding='utf-8') as f:
                self._config = yaml.safe_load(f)

            if not self._config:
                raise ValueError("配置文件为空")

        except Exception as e:
            raise RuntimeError(f"加载配置文件失败: {e}")

    def _parse_api_config(self) -> APIConfig:
        """解析API配置"""
        api_config = self._config.get('api', {})
        return APIConfig(
            account=api_config.get('account', ''),
            password=api_config.get('password', ''),
            url=api_config.get('url', ''),
            debug=api_config.get('debug', False),
            web_gui=api_config.get('web_gui', False)
        )

    def _parse_strategy_config(self) -> StrategyConfig:
        """解析策略配置"""
        strategy_config = self._config.get('strategy', {})
        return StrategyConfig(
            name=strategy_config.get('name', 'default_strategy'),
            symbol=strategy_config.get('symbol', ''),
            volume=strategy_config.get('volume', 1),
            short_period=strategy_config.get('short_period', 5),
            long_period=strategy_config.get('long_period', 20)
        )

    def _parse_risk_config(self) -> RiskConfig:
        """解析风险管理配置"""
        risk_config = self._config.get('risk', {})
        return RiskConfig(
            max_daily_loss=risk_config.get('max_daily_loss', 5000),
            max_single_loss=risk_config.get('max_single_loss', 1000),
            max_position_size=risk_config.get('max_position_size', 10),
            stop_loss_points=risk_config.get('stop_loss_points', 50),
            take_profit_points=risk_config.get('take_profit_points', 150),
            enable_trailing_stop=risk_config.get('enable_trailing_stop', False),
            trailing_stop_points=risk_config.get('trailing_stop_points', 30)
        )

    def _parse_data_config(self) -> DataConfig:
        """解析数据配置"""
        data_config = self._config.get('data', {})
        return DataConfig(
            kline_period=data_config.get('kline_period', 60),
            data_length=data_config.get('data_length', 200),
            cache_enabled=data_config.get('cache_enabled', True),
            cache_ttl=data_config.get('cache_ttl', 300)
        )

    def _parse_logging_config(self) -> LoggingConfig:
        """解析日志配置"""
        logging_config = self._config.get('logging', {})
        return LoggingConfig(
            level=logging_config.get('level', 'INFO'),
            file_path=logging_config.get('file_path', 'logs/trader.log'),
            max_file_size=logging_config.get('max_file_size', 10485760),
            backup_count=logging_config.get('backup_count', 5),
            console_output=logging_config.get('console_output', True)
        )

    def _parse_trading_config(self) -> TradingConfig:
        """解析交易配置"""
        trading_config = self._config.get('trading', {})
        return TradingConfig(
            max_orders_per_minute=trading_config.get('max_orders_per_minute', 10),
            order_timeout=trading_config.get('order_timeout', 30),
            retry_attempts=trading_config.get('retry_attempts', 3),
            retry_delay=trading_config.get('retry_delay', 1.0),
            enable_simulation=trading_config.get('enable_simulation', False)
        )

    def _parse_monitoring_config(self) -> MonitoringConfig:
        """解析监控配置"""
        monitoring_config = self._config.get('monitoring', {})
        return MonitoringConfig(
            health_check_interval=monitoring_config.get('health_check_interval', 60),
            performance_report_interval=monitoring_config.get('performance_report_interval', 300),
            enable_metrics=monitoring_config.get('enable_metrics', True),
            metrics_port=monitoring_config.get('metrics_port', 9090)
        )

    def get(self, key: str, default: Any = None) -> Any:
        """获取配置值"""
        keys = key.split('.')
        value = self._config

        for k in keys:
            if isinstance(value, dict):
                value = value.get(k)
            else:
                return default

        return value if value is not None else default

    def set(self, key: str, value: Any):
        """设置配置值"""
        keys = key.split('.')
        config = self._config

        for k in keys[:-1]:
            if k not in config:
                config[k] = {}
            config = config[k]

        config[keys[-1]] = value

    def save(self):
        """保存配置到文件"""
        try:
            # 确保目录存在
            self.config_file.parent.mkdir(parents=True, exist_ok=True)

            with open(self.config_file, 'w', encoding='utf-8') as f:
                yaml.dump(self._config, f, default_flow_style=False, allow_unicode=True)

        except Exception as e:
            raise RuntimeError(f"保存配置文件失败: {e}")

    def reload(self):
        """重新加载配置"""
        self._load_config()

        # 重新解析配置
        self.api = self._parse_api_config()
        self.strategy = self._parse_strategy_config()
        self.risk = self._parse_risk_config()
        self.data = self._parse_data_config()
        self.logging = self._parse_logging_config()
        self.trading = self._parse_trading_config()
        self.monitoring = self._parse_monitoring_config()


# 全局配置实例
_config_manager = None

def get_config() -> ConfigManager:
    """获取全局配置实例"""
    global _config_manager
    if _config_manager is None:
        _config_manager = ConfigManager()
    return _config_manager


def init_config(config_file: str = None) -> ConfigManager:
    """初始化配置管理器"""
    global _config_manager
    _config_manager = ConfigManager(config_file)
    return _config_manager
